845d9d0eed0f6556e11ee7f7204fda9c8dd41154,dx/src/com/android/dx/command/dexer/Main.java,Main,processAllFiles,#,468

Before Change


        anyFilesProcessed = false;
        String[] fileNames = args.fileNames;

        if (args.numThreads > 1) {
            threadPool = Executors.newFixedThreadPool(args.numThreads);
            parallelProcessorFutures = new ArrayList<Future<Void>>();
        }

        try {
            if (args.mainDexListFile != null) {
                // with --main-dex-list
                FileNameFilter mainPassFilter = args.strictNameCheck ? new MainDexListFilter() :
                    new BestEffortMainDexListFilter();

                // forced in main dex
                for (int i = 0; i < fileNames.length; i++) {
                    processOne(fileNames[i], mainPassFilter);
                }

                if (dexOutputArrays.size() > 0) {
                    throw new DexException("Too many classes in " + Arguments.MAIN_DEX_LIST_OPTION
                            + ", main dex capacity exceeded");
                }

                if (args.minimalMainDex) {
                    // start second pass directly in a secondary dex file.
                    rotateDexFile();
                }

                // remaining files
                for (int i = 0; i < fileNames.length; i++) {
                    processOne(fileNames[i], new NotFilter(mainPassFilter));
                }
            } else {
                // without --main-dex-list
                for (int i = 0; i < fileNames.length; i++) {
                    processOne(fileNames[i], ClassPathOpener.acceptAll);
                }
            }
        } catch (StopProcessing ex) {
            /*
             * Ignore it and just let the error reporting do
             * their things.
             */
        }

        if (args.numThreads > 1) {
            try {
                threadPool.shutdown();
                if (!threadPool.awaitTermination(600L, TimeUnit.SECONDS)) {
                    throw new RuntimeException("Timed out waiting for threads.");
                }
            } catch (InterruptedException ex) {
                threadPool.shutdownNow();
                throw new RuntimeException("A thread has been interrupted.");
            }

            try {
              for (Future<?> future : parallelProcessorFutures) {
                future.get();
              }
            } catch (ExecutionException e) {
                Throwable cause = e.getCause();
                // All Exceptions should have been handled in the ParallelProcessor, only Errors
                // should remain
                if (cause instanceof Error) {
                    throw (Error) e.getCause();
                } else {
                    throw new AssertionError(e.getCause());
                }
            } catch (InterruptedException e) {
              // If we're here, it means all threads have completed cleanly, so there should not be
              // any InterruptedException
              throw new AssertionError(e);
            }
        }

After Change


        String[] fileNames = args.fileNames;

        // translate classes in parallel
        classTranslatorPool = new ThreadPoolExecutor(args.numThreads,
               args.numThreads, 0, TimeUnit.SECONDS,
               new ArrayBlockingQueue<Runnable>(2 * args.numThreads, true),
               new ThreadPoolExecutor.CallerRunsPolicy());
        // collect translated and write to dex in order
        classDefItemConsumer = Executors.newSingleThreadExecutor();


        try {
            if (args.mainDexListFile != null) {
                // with --main-dex-list
                FileNameFilter mainPassFilter = args.strictNameCheck ? new MainDexListFilter() :
                    new BestEffortMainDexListFilter();

                // forced in main dex
                for (int i = 0; i < fileNames.length; i++) {
                    processOne(fileNames[i], mainPassFilter);
                }

                if (dexOutputFutures.size() > 0) {
                    throw new DexException("Too many classes in " + Arguments.MAIN_DEX_LIST_OPTION
                            + ", main dex capacity exceeded");
                }

                if (args.minimalMainDex) {
                    // start second pass directly in a secondary dex file.

                    // Wait for classes in progress to complete
                    synchronized(dexRotationLock) {
                        while(maxMethodIdsInProcess > 0 || maxFieldIdsInProcess > 0) {
                            try {
                                dexRotationLock.wait();
                            } catch(InterruptedException ex) {
                                /* ignore */
                            }
                        }
                    }

                    rotateDexFile();
                }

                // remaining files
                for (int i = 0; i < fileNames.length; i++) {
                    processOne(fileNames[i], new NotFilter(mainPassFilter));
                }
            } else {
                // without --main-dex-list
                for (int i = 0; i < fileNames.length; i++) {
                    processOne(fileNames[i], ClassPathOpener.acceptAll);
                }
            }
        } catch (StopProcessing ex) {
            /*
             * Ignore it and just let the error reporting do
             * their things.
             */
        }

        try {
            classTranslatorPool.shutdown();
            classTranslatorPool.awaitTermination(600L, TimeUnit.SECONDS);
            classDefItemConsumer.shutdown();
            classDefItemConsumer.awaitTermination(600L, TimeUnit.SECONDS);

            for (Future<Boolean> f : addToDexFutures) {
                try {
                    f.get();
                } catch(ExecutionException ex) {
                    // Catch any previously uncaught exceptions from
                    // class translation and adding to dex.
                    int count = errors.incrementAndGet();
                    if (count < 10) {
                        DxConsole.err.println("Uncaught translation error: " + ex.getCause());
                    } else {
                        throw new InterruptedException("Too many errors");
                    }
                }
            }